home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / infor / excp13.zip / EXCEPT13.TEC
Text File  |  1993-03-02  |  19KB  |  342 lines

  1. ID:13 QEMM-386:  Exception #13 explained
  2. Quarterdeck Technical Note #142
  3. By: Michael Bolton
  4. Last revision: 2 March 1993
  5.  
  6. Q. What is an Exception #13?  What is an Exception #12?
  7. Q. What does the QEMM Exception message mean?  How can it help me?
  8.  
  9. Users of QEMM-386 may sometimes encounter a report that an attempt has been
  10. made to execute an invalid instruction.  It is almost certain that QEMM-386,
  11. in and of itself, is not the cause of Exception #13 problems, though
  12. QEMM-386's memory managment may come into conflict with other hardware and
  13. software on your system.
  14.  
  15. Quarterdeck Technical Note #232, Exception #13 Advanced Troubleshooting
  16. (EX13FLOW.TEC) is designed to resolve conflicts in which QEMM-386 may be
  17. involved.  This technical note is its companion; here we explain in detail
  18. what a processor exception is, how you can interpret the information provided
  19. by the exception report, and what you can do to remedy the situation in the
  20. unhappy event that the techniques in EX13FLOW.TEC don't provide relief from
  21. the problem.
  22.  
  23. To answer the questions above, it's worthwhile to examine the Exception #13
  24. report bit by bit.
  25.  
  26. "The processor has notified QEMM that an attempt has been made to execute an
  27. invalid instruction..."
  28.  
  29. Exceptions are the processor's response to unusual, invalid, or special
  30. conditions in the normal operation of the 80386 processor and others in its
  31. family.  (The 80386 family includes the 80386SX, the 80386DX, the 80486SX, and
  32. the 80486DX processors; their memory management architecture is essentially
  33. the same.  In this document, the term "386" refers to any and all of these
  34. processors.)  Exceptions cause the 386 processor to stop what it's doing and
  35. to try to react to the condition that caused the exception.  QEMM-386 is
  36. designed to capture some of these exceptions -- particularly those caused by
  37. protection faults or invalid instructions, which could cause a program or the
  38. entire system to crash -- and display a report to the user.  When the
  39. processor encounters an instruction that it does not want to execute, it
  40. passes control to the protected mode interrupt 13 (decimal) handler.
  41. QEMM-386's protected mode INT 13 handler posts the Exception #13 message.
  42. Neither DOS nor Microsoft's EMM386.EXE have a protected mode interrupt 13
  43. handler, so if an exception occurs using only DOS or EMM386.EXE, your system
  44. simply crashes and you have no report.
  45.  
  46.  
  47. Q. What causes an Exception #12 or Exception #13?
  48.  
  49. "...This may be due to an error in one of your programs, a conflict between
  50. two pieces of software, or a conflict between a piece of hardware and a piece
  51. of software...."
  52.  
  53. The exception reported is most commonly #13, the General Protection Fault
  54. exception.  This indicates that a program has tried to execute an invalid or
  55. privileged instruction.  On the 386 processor, programs can run at varying
  56. privilege levels, so that the processor can better protect application
  57. programs (which generally run at lower privilege levels) from crashing the
  58. operating system or control program (which typically runs at the highest
  59. privilege level).  DOS and QEMM-386 do not enforce this protection, but
  60. QEMM-386 can report when a program running at the lowest privilege level tries
  61. to execute a privileged instruction.  The result may be a system crash, but
  62. QEMM-386 does provide a report before the crash happens.
  63.  
  64. Invalid instructions are harder to classify, for indeed Exception #13 is
  65. something of a catch-all.  Some examples of invalid instructions include:
  66.  
  67. - 386-specific instructions that are disallowed when the processor is in
  68.   virtual 8086 mode.  The processor is in this mode whenever QEMM-386 is in an
  69.   ON state -- essentially when it is providing expanded memory or High RAM.
  70.  
  71. - A program trying to write data to a segment that has been marked as
  72.   executable or read-only (the data could overwrite program code).
  73.  
  74. - Trying to run program code from a data segment (if data is read as code, it
  75.   will be a series of meaningless or nonsensical instructions -- which, if
  76.   executed, could jump to invalid addresses or overwrite the operating system)
  77.  
  78. - Exceeding the limit of a segment.  Segments in virtual 8086 mode are not
  79.   permitted to exceed FFFFh (65535 decimal) bytes or to fall below 0 bytes.
  80.   Neither a program instruction nor a memory reference may span the boundary
  81.   of a segment.
  82.  
  83. It is this last which is the most common; this is a problem also known as
  84. "segment wrap", which we will discuss later.  Again, QEMM-386 is designed to
  85. trap and report these errors, but it cannot defend against the system crashes
  86. that they may cause.
  87.  
  88. Occasionally Exception #12, indicating a stack exception, will be reported.
  89. This is a protection violation very similar to Exception #13, but is one in
  90. which the stack segment is involved in some way.  Although no easier to solve,
  91. it is a somewhat less general report than Exception #13.
  92.  
  93. Very infrequently, an Exception #0 is reported.  This is not intentional; it
  94. is usually the result of QEMM's stack being corrupted while QEMM was trying to
  95. report another exception, or is the result of some other system error.
  96.  
  97. It is important to remember that in the vast majority of cases, QEMM-386 is
  98. not involved with the problem, but is merely reporting it.
  99.  
  100.  
  101. Q.  What do I do now?
  102.  
  103. "...It is likely that the system is unstable now and should be rebooted...."
  104.  
  105. QEMM-386 is designed to offer the user the opportunity to terminate the
  106. offending program, or to reboot the computer, but often the damage has already
  107. been done by the time that the exception is trapped and reported.  In this
  108. instance, you may find the computer locked regardless of what you choose.  If
  109. the computer is indeed hung, you should write down the information on the
  110. screen and then reboot the machine.
  111.  
  112. While QEMM-386's exception reports can be cryptic to non-programmers -- or to
  113. programmers who have little experience with assembly language -- the
  114. information that they provide can sometimes be quite helpful. Exception
  115. reports can help you to identify which program has triggered the exception
  116. message, what the invalid instruction was, and the state of the processor's
  117. registers when the error occurred.  Armed with this information, you may be
  118. able to help the developer of the offending application to determine the
  119. problem that led to the exception, and thus the developer may be able to
  120. provide a temporary workaround or a permananent fix.
  121.  
  122. The exception report is divided into three parts --
  123.  
  124. 1) The vector or class of exception, and its location and error code. The
  125. location of the exception indicates the address in memory at which the invalid
  126. instruction was attempted.  The program loaded at this address (if indeed a
  127. program is loaded there) should be noted by running Manifest.
  128.  
  129. Exception #13 at 1B12:0103, error code: 0000
  130.  
  131. In this example, the program loaded at address 1B12:xxxx is automatically your
  132. suspect.  Reboot your system in the same configuration as you had when the
  133. Exception #13 occurred.  If the problem happened during an application
  134. program, don't load the application just yet.  Load Manifest instead, and have
  135. a look at First Meg / Programs.
  136.  
  137. Memory Area   Size   Description
  138. 03D1 - 0465   2.3K  COMMAND
  139. 0466 - 046A   0.1K  (04C0)
  140. 046B - 0483   0.4K  COMMAND Environment
  141. 0484 - 0487   0.1K  COMMAND Data
  142. 0488 - 0498   0.3K  DV Environment
  143. 0499 - 04BE   0.6K  DV
  144. 04BF - 1A38    85K  DV Data
  145. 1A39 - 1A52   0.4K  COMMAND Data
  146. 1A53 - 1AE7   2.3K  COMMAND
  147. 1AE8 - 1B00   0.4K  COMMAND Environment
  148. 1B01 - 7E4F   397K  [Available]
  149.  
  150. The sample Exception #13 above happened in that Available range, so it was the
  151. program that would have been loaded had we not loaded Manifest -- that is, the
  152. application program.  If you have a TSR loaded low, and the Exception #13 is
  153. occuring within that TSR's address space, then it is your suspect, rather than
  154. the application.  In any case, the program whose code falls into the range in
  155. which the Exception #13 occurred likely has a problem of some type.
  156.  
  157. 2)  The second part of the Exception #13 message is the register dump:
  158.  
  159. AX=0000 BX=0000 CX=0000 DX=0000 SI=FFFF DI=0000 BP=0000
  160. DS=1B12 ES=1B12 SS=1B12 SP=FFFE Flags=7246
  161.  
  162. The registers are the temporary storage areas on the 80386 chip which are used
  163. for calculations and addressing.  Each register is two bytes (16 bits) in
  164. size, so each register is capable of holding a value from 0 to FFFF
  165. (hexadecimal), or from 0 to 65335 (decimal).
  166.  
  167. If any registers here are 0000 or FFFF, it's possible that you could be
  168. looking at a segment wrap.  A segment wrap happens whenever a program attempts
  169. to access -- read from or write to -- something beyond the limit of a segment.
  170. A word value consists of two adjacent bytes; if a word value were to begin at
  171. FFFF (which is the last byte of a segment), the second byte of that value will
  172. be outside the segment -- and an attempt to read from or write to that word
  173. will thus cause a protection violation.  Similarly, a doubleword is four
  174. adjacent bytes; if any of the last three bytes are outside of the segment
  175. limit, a segment wrap and a protection violation will occur when an access is
  176. attempted.
  177.  
  178. On an 8086 processor, it's actually possible for a segment wrap to occur
  179. without a protection violation, simply because the 8086 has no hardware
  180. protection at all.  What is the byte after the last byte of a segment? On the
  181. 8086, it's the FIRST byte of the same segment.  (Non-technical analogy for
  182. poker players: Queen - King - Ace - Two - Three is a straight in the
  183. penny-ante poker game played when the 8086 processor is dealing.  The 386
  184. processor is a very strict dealer, and does not permit this.)  It is possible
  185. (though unlikely) for a program to continue without a crash on an 8086
  186. processor when two "adjacent" bytes are actually a whole segment apart; it
  187. could theoretically be possible on a 386 too, but the exception is generated
  188. before the memory access can be completed.
  189.  
  190. This sort of problem is seen most commonly during a string move -- the program
  191. is copying a whole block of data from one range of addresses to another.  You
  192. may not understand this, and actually it doesn't matter if you don't.
  193. Briefly, though, SI stands for Source Index; DI stands for Destination Index.
  194. These two registers are used for string instructions -- instructions that load
  195. or copy information sequentially.  String instructions are extremely powerful
  196. and useful, since they allow the developer to deal with large amounts of data
  197. in a single pass.  A byte or a word value can be fetched from memory by one
  198. string instruction, dealt with, and then the result can be copied to a new
  199. memory location with a second string instruction -- and all this can be
  200. managed with an extremely tight, fast loop.  An entire range of addresses (for
  201. example, in screen memory) can even be filled with a given value using a
  202. single instruction.  The catch here is that the string instruction is only
  203. valid as long as the value of the SI or DI register does not fall outside the
  204. range addressable by these registers.  If either one of these tries to exceed
  205. FFFF (or tries to fall below 0000), as a string is being copied from one
  206. region of memory to another, you'll get a protection violation.
  207.  
  208. 3)       Instruction: A5 CC 00 00 00 00 00 00 00 00 00 00 00 00 00
  209.          Do you want to (T)erminate the program or (R)eboot?
  210.  
  211. This is the invalid instruction that the program was trying to execute when
  212. the processor stopped it.  Since most humans don't have a hope of interpreting
  213. machine language by looking at the opcodes, you can get a better
  214. interpretation of what is going on by examining this instruction with a
  215. program that can render machine codes into assembly language. (Well... it's
  216. better than nothing.)  To do so, go into DEBUG; type DEBUG at the DOS prompt.
  217.  
  218. Enter the values from the Instruction line by typing
  219.  
  220. E 100
  221.  
  222. at DEBUG's hyphen prompt, and then entering each byte (pair of digits) from
  223. the instruction line.  Follow each byte with a space.
  224.  
  225. (As a bonus -- if you're running under DESQview, you can Mark the information
  226. from the Exception #13 report, and Transfer it into DEBUG running in a
  227. different Big DOS window.)
  228.  
  229. If most of the bytes begin with a 4, 5, 6, or 7, there's a good chance that
  230. you're seeing a program trying to execute text, thinking that text to be code.
  231. This can happen in several circumstances, but frequent offenders are those
  232. programs which load code at the top of conventional memory during boot -- and
  233. therefore during the OPTIMIZE process -- and presume that no program will
  234. allocate that memory.  Programs which place parts of themselves at the top of
  235. conventional memory typically do so without protecting themselves from
  236. programs like LOADHI which may need to allocate all conventional memory at
  237. appropriate times; LOADHI (and programs like it) will overwrite the vulnerable
  238. code.
  239.  
  240. As a real-world example, PROTMAN, a program whose purpose in life is to manage
  241. the loading of various parts of 3Com and MS-LAN networks, did this in past
  242. versions, as explained in Quarterdeck Technical Note #173, PROTMAN.TEC.
  243. During the OPTIMIZE process, LOADHI would allocate all conventional memory
  244. while it was determining the size of the various drivers that were being
  245. loaded. PROTMAN would jump to what it thought was still its own code, but
  246. there would be LOADHI signatures there -- text -- and PROTMAN would crash.
  247.  
  248. You can see the contents of this string if you Dump the instruction you just
  249. entered; use DEBUG's D instruction to do this.
  250.  
  251. -d 100
  252.  
  253. 1DC0:0100  4F 41 44 48 49 53 49 47-4E 41 54 55 52 BF 42 87 LOADHISIGNATUREB
  254. 1DC0:0110  98 FF 6F E2 E9 FF 00 00-26 21 F1 B3 34 00 AF 1D ..o.....&!..4...
  255. 1DC0:0120  01 00 D3 E0 0B E8 59 5F-07 B0 00 AA 5F 9D F8 C3 ......Y_...._...
  256. 1DC0:0130  AA 41 FE 06 AD 90 C3 2E-C7 06 CF 88 00 00 2E 89 .A..............
  257.  
  258. ASCII codes starting with 2 are generally punctuation marks; bytes 30-39
  259. represent numeric digits; 3A-3F are punctuation, 41-5A are capital letters,
  260. 61-7A are small letters.  Any instruction made up mostly of these numbers is
  261. almost certainly text -- and therefore not executable program code.  The
  262. program that is trying to run such an instruction is doing so in error. When
  263. the instructions are NOT mostly in the 40-80 range, you should try to
  264. Unassemble them.
  265.  
  266. -u 100
  267.  
  268. 20C0:0100 A5            MOVSW
  269. 20C0:0101 CC            INT     3
  270. 20C0:0102 0000          ADD     [BX+SI],AL
  271.  
  272. This is the killer instruction from the example Exception #13 above. It's
  273. performing a MOVSW (MOVe String Word) at a point when the SI register is FFFF,
  274. and that means that it's trying to write a word value to or from the last byte
  275. of a segment, which (as described above) is illegal.
  276.  
  277. Other invalid instructions are harder for the non-programmers of the world to
  278. interpret.  Often the first byte of an invalid instruction is 0F -- which is a
  279. valid protected-mode instruction, but which the processor interprets as an
  280. invalid opcode if the machine is in Virtual 86 mode.  Exceptions of this kind
  281. showed up more commonly in the past, with programs that were trying to enter
  282. protected mode without calling the Virtual Control Program Interface.  VCPI is
  283. an industry-standard way for protected-mode software to coexist with 386
  284. expanded memory managers such as QEMM-386; all 386 memory managers these days
  285. are VCPI-providers, and almost all protected-mode programs are VCPI users (or
  286. "clients").  Non-VCPI protected-mode programs include some memory- and
  287. hardware-diagnostic programs, and programs that use the DPMI memory management
  288. specification exclusively.  Diagnostic programs typically recommend that you
  289. disable all memory-management software during diagnosis.  DPMI programs will
  290. typically accept VCPI memory management; those rare programs that do not will
  291. simply refuse to start up under QEMM-386.  In such cases, you may install
  292. QDPMI (the Quarterdeck DPMI Host) on your system; QDPMI is available on the
  293. Quarterdeck BBS at (310) 314-3227, Compuserve (!GO QUARTERDECK), or large
  294. local BBS systems.
  295.  
  296. How can an Exception #13 be fixed?  Two Quarterdeck Technical Notes can help
  297. you determine if you can solve the problem yourself.  Quarterdeck Technical
  298. Note #241, QEMM-386:  General Troubleshooting (TROUBLE.TEC) is a good place to
  299. start.  This note describes common problems and possible solutions, and will
  300. help if the cause of the Exception #13 is a memory conflict or bus-mastering
  301. issue.  Quarterdeck Technical Note #232, Exception #13 Advanced
  302. Troubleshooting (EX13FLOW.TEC) should help you to determine if there is
  303. anything at all that you can do yourself to fix the problem.
  304.  
  305. If you follow the instructions in both of these technical notes completely,
  306. and the Exception #13 persists, the prospects for a resolution are bleak,
  307. since the problem is almost certainly a bug in the offending program.  If this
  308. is so, unless you can alert the developer of the program (and make him or her
  309. understand all this, which might be another task altogether), you can never
  310. really make the problem go away, although sometimes you may be able to make it
  311. subside.
  312.  
  313. Changing the location of the offending program in memory will sometimes help.
  314. If you're running under DESQview, and you're sure that you've given the
  315. program enough memory (i.e., all you can give it), try adding 16 to the size
  316. of the script buffer on page 2 of Change a Program.  If you're not running
  317. under DESQview, try adding an extra file handle or two.  The key here is to
  318. change the location of the program in memory, which can occasionally be enough
  319. to provide temporary relief from the Exception #13.
  320.  
  321. There is a substantial caveat:  You're not fixing the problem by doing this;
  322. you're just making it submerge.  There's still probably a bug in the offending
  323. program -- you've just changed it from a bomb to a landmine.  If you can
  324. reproduce the problem consistently, you should still contact the publisher of
  325. the application with all of the data from the Exception #13 message, and all
  326. of the data that you can supply about your system and its current
  327. configuration.
  328.  
  329. With the exception (no pun intended) of the techniques mentioned above and in
  330. EX13FLOW.TEC, non-programmers can do little to fix the root cause or even the
  331. symptoms of Exception #13.  If you are unsuccessful in resolving a conflict,
  332. the information provided by the report should be forwarded, along with a
  333. Manifest printout and a complete description of your system, to the developer
  334. of the program that you were running at the time.
  335.  
  336.   ************************************************************************
  337.   *          Trademarks are property of their respective owners.         *
  338.   *This technical note may be copied and distributed freely as long as it*
  339.   *is distributed in its entirety and it is not distributed for profit.  *
  340.   *          Copyright (C) 1993 by Quarterdeck Office Systems            *
  341.   ************************ E N D   O F   F I L E *************************
  342.